package common.helper.toolkit;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.http.*;
import com.google.api.client.http.javanet.NetHttpTransport;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

/*
https://www.mkyong.com/java/how-to-send-http-request-getpost-in-java/
 */


/**
 * Created by pkuderc on 5/29/16.
 */
public class HttpToolkit {

    public static class HostPortPair{
        public String host;
        public int port;
    }

    public static final Logger logger = LoggerFactory.getLogger(HttpToolkit.class);

    public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    public static final ObjectMapper mapper = new ObjectMapper();














    /*
    *****************************************************************************
     */


    /*
	 * https://developers.google.com/api-client-library/java/google-http-java-client/samples
	 * https://developers.google.com/api-client-library/java/google-http-java-client/transport
	 */
    private static HttpRequestFactory getHttpRequestFactory() {
        HttpRequestFactory requestFactory =
                HTTP_TRANSPORT.createRequestFactory(new HttpRequestInitializer() {
                    @Override
                    public void initialize(HttpRequest request) {
                        //request.setParser(new JsonObjectParser(JSON_FACTORY));
                    }
                });
        return requestFactory;
    }

    public static HostPortPair getHostPortPair(String filePath) {
        String json = FileToolkit.readStringFromFile(filePath);
        //logger.debug("HTTP Address : \n {}",json);

        Document bson = Document.parse(json);
        List<Document> servers = (List<Document>) bson.get("servers");

        HostPortPair pair = new HostPortPair();
        for(Document server : servers) {
            String host = server.getString("host");
            Integer port = server.getInteger("port");
            if(host!=null && port!=null){
                pair.host = host;
                pair.port = port;
                break;
            }
        }
        return pair;
    }

    public static String getHostPort(String filePath) {
        HostPortPair pair = getHostPortPair(filePath);
        String urlStr = "http://" + pair.host + ":" + pair.port + "/";
        return urlStr;
    }

    private static String executeHttp(HttpRequest request){
        HttpResponse response = null;
        String output = "";
        try {
            response = request.execute();
        } catch (IOException e) {
            //e.printStackTrace();
            //output = request.getUnsuccessfulResponseHandler().toString();
            String[] outputs = e.getLocalizedMessage().split("\n");
            output = outputs[outputs.length - 1];
            return output;
        }

        InputStream content = null;
        try {
            content = response.getContent();
            output = FileToolkit.readAllStringFromStream(content);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            response.disconnect();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //logger.debug("rest_output = {}\n" , output);
        return output;
    }

    /*
    rest_put
     */
    public static String rest_put(String url, String input){
        logger.debug("PUT : \n {} \n {}",url, input);
        GenericUrl genericUrl = new GenericUrl(url);
        InputStream inputStream = FileToolkit.getInputStreamFromString(input);
        InputStreamContent content = new InputStreamContent("application/json", inputStream );
        HttpRequestFactory requestFactory = getHttpRequestFactory();
        HttpRequest request = null;
        try {
            request = requestFactory.buildPutRequest(genericUrl,content);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String output = executeHttp(request);
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return output;
    }


    /*
    rest_post
     */
    public static String rest_post(String url, String input){
        logger.debug("POST : \n {} \n {}",url, input);
        GenericUrl genericUrl = new GenericUrl(url);
        InputStream inputStream = FileToolkit.getInputStreamFromString(input);
        InputStreamContent content = new InputStreamContent("application/json", inputStream );
        HttpRequestFactory requestFactory = getHttpRequestFactory();
        HttpRequest request = null;
        try {
            request = requestFactory.buildPostRequest(genericUrl,content);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String output = executeHttp(request);
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return output;
    }

    /*
    rest_get
     */
    public static String rest_get(String url){
        logger.debug("GET : \n {}",url);
        GenericUrl genericUrl = new GenericUrl(url);
        HttpRequestFactory requestFactory = getHttpRequestFactory();
        HttpRequest request = null;
        try {
            request = requestFactory.buildGetRequest(genericUrl);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String  output = executeHttp(request);

        return output;
    }

    /*
    rest_delete
     */
    public static String rest_del(String url){
        logger.debug("DELETE : \n {}",url);
        GenericUrl genericUrl = new GenericUrl(url);
        HttpRequestFactory requestFactory = getHttpRequestFactory();
        HttpRequest request = null;
        try {
            request = requestFactory.buildDeleteRequest(genericUrl);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String output = executeHttp(request);
        return output;
    }


    /*
    **********************************************************************************
    * USE NEW HTTP CLIENT
     */

    private static final String USER_AGENT = "Mozilla/5.0";


    // HTTP GET request
    public static String REST_GET(String url)  {
        String ret_str = "";
        try{
            logger.info("[REST_GET] url = {}",url);
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();

            // optional default is GET
            con.setRequestMethod("GET");

            //add request header
            con.setRequestProperty("User-Agent", USER_AGENT);

            int responseCode = con.getResponseCode();
            logger.info("[REST_GET] ret_code = {}", responseCode);
            //System.out.println("\nSending 'GET' request to URL : " + url);
            //System.out.println("Response Code : " + responseCode);

            BufferedReader in = new BufferedReader(
                    new InputStreamReader( con.getInputStream() )
            );
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            //print result
            //System.out.println(response.toString());
            ret_str =  response.toString();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return ret_str;
    }


    // HTTP POST request
    public static String REST_POST(String url, String input ) {

        //String url = "https://selfsolve.apple.com/wcResults.do";
        String ret_str = "";
        try{
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();

            //add reuqest header
            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", USER_AGENT);
            con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

            //String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345";

            // Send post request
            con.setDoOutput(true);
            DataOutputStream wr = new DataOutputStream(con.getOutputStream());
            wr.writeBytes(input);
            wr.flush();
            wr.close();

            int responseCode = con.getResponseCode();
            //System.out.println("\nSending 'POST' request to URL : " + url);
            //System.out.println("Post parameters : " + input);
            //System.out.println("Response Code : " + responseCode);

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(con.getInputStream())
            );
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            //print result
            //System.out.println(response.toString());
            ret_str = response.toString();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return ret_str;
    }







    /*
    ****************************** main ****************************************
    */
    public static void main(String[] args){

        test_request();

        /*
        String host_port = getHostPort("/elastic_admin/http_servers.json");
        String url = host_port + "index_test";
        */

        /*
        backup rest_del
         */
        //logger.debug("HttpDelUrl = {}", url);
        //String delString = rest_del(url);
        //logger.debug("HttpDelOutput = {}", delString);

        /*
        backup rest_put
         */
        /*
        logger.debug("HttpPutUrl = {}", url);
        String json = FileToolkit.readStringFromFile("/elastic_admin/_settings.json");
        logger.debug("HttpPutInput = {}", json);
        String setString = rest_put(url , json);
        logger.debug("HttpPutOutput = {}", setString);
        */
         /*
        backup rest_del
         */
        //logger.debug("HttpDelUrl = {}", url);
        //String delString2 = rest_del(url);
        //logger.debug("HttpDelOutput = {}", delString2);

    }



    public static void test_request(){
        String url = "http://www.qq.com";
        String output = rest_get(url);
        System.out.println("[output] = \n" + output);
    }

}


